interface NodeData {
  id: number;
  pid: number;
  layer: number;
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  [key: string]: any; // 用于保留额外数据
}

interface X6Node {
  id: number | string;
  shape: string;
  width: number;
  height: number;
  x: number;
  y: number;
  data: NodeData;
}

interface X6Edge {
  source: number | string | { cell: string; port: string };
  target: number | string | { cell: string; port: string };
  attrs: {
    line: {
      fill?: string;
      strokeLinejoin?: string;
      strokeWidth?: number;
      stroke: string;
      targetMarker: null;
      sourceMarker: null;
    };
  };
  router?: {
    name: string;
    args: {
      offset: string;
      direction: string;
    };
  };
}

interface CalcNode extends NodeData {
  width: number;
  height: number;
  subTreeWidth: number;
  subTreeHeight: number;
  usedWidth: number;
}

interface CollapsableNode {
  shape: string;
  width: number;
  height: number;
  borderRadius: number;
  x: number;
  y: number;
  data?: {
    expand: boolean;
    children: number[];
    self: number;
    layer: number;
  };
  ports: {
    bottom: {
      position: string;
      attrs: {
        rect: {
          magnet: boolean;
          stroke: string;
        };
      };
    };
  };
}

interface TreeData {
  nodes: X6Node[];
  edges: X6Edge[];
  size: {
    width: number;
    height: number;
  };
}
interface TreeDataParams {
  data: NodeData[];
  nodeWidth?: number;
  nodeHeight?: number;
  numberWidth?: number;
  numberHeight?: number;
  customWidth?: number;
  customHeight?: number;
  layerGutter?: number;
  nodeGutter?: number;
  smallCustomHeight?: number;
  smallCustomWidth?: number;
  lineCardWidth?: number;
  lineCardHigth?: number;
}
interface LayerResult {
  exists: boolean;
  layer: number;
}
function findLayerWithNumberType(dataCopy) {
  // 创建一个对象来跟踪每个 layer 是否包含 'Number' 类型
  const layerMap = {};

  // 遍历 dataCopy 数组
  for (const item of dataCopy) {
    const { layer, type } = item;

    // 初始化 layerMap 中的 layer 条目
    if (!layerMap[layer]) {
      layerMap[layer] = {
        hasNumber: false,
        count: 0
      };
    }

    // 增加该 layer 的对象计数
    layerMap[layer].count += 1;

    // 如果类型为 'Number'，标记该 layer 包含 'Number'
    if (type === "Number") {
      layerMap[layer].hasNumber = true;
    }
  }

  // 收集所有符合条件的层
  const result: LayerResult[] = [];
  for (const layer in layerMap) {
    if (layerMap[layer].hasNumber && layerMap[layer].count > 1) {
      result.push({ exists: true, layer: parseInt(layer, 10) });
    }
  }

  return result;
}

export const treeDataConfig = {
  nodeWidth: 428,
  nodeHeight: 265,
  customWidth: 1050,
  customHeight: 800,
  smallCustomWidth: 450,
  smallCustomHeight: 800,
  numberWidth: 50,
  numberHeight: 50,
  layerGutter: 250,
  nodeGutter: 100,
  lineCardWidth: 428,
  lineCardHeight: 265
};
function calculateNodeHeight(node, nodeHeight) {
  // 当节点类型为 Card 且 isDetail 存在
  if (node.type === "Card") {
    if (node.isDetail) {
      // 如果 departmentName 不存在，返回 nodeHeight - 50
      if (!node.departmentName) {
        return nodeHeight - 50;
      }
      // 否则返回原始高度
      return nodeHeight;
    }
  } else if (node.type === "Number") {
    // 如果节点类型为 Number，返回原始高度
    return nodeHeight;
  }

  // 默认情况下，返回 nodeHeight - 50
  return nodeHeight - 50;
}

// function calculateNodeHeight (node: NodeData, nodeHeight: number): number {
//   if (node.type === 'Card' && node.isDetail) {
//     return nodeHeight // 如果是 Card 类型且是详细信息，返回原始高度
//   }

//   if (node.type === 'Card' && !node.isDetail && node.deptLevel) {
//     return nodeHeight // 如果是 Card 类型且不是详细信息且 deptLevel 存在，返回原始高度
//   }

//   if (node.type === 'Number') {
//     return nodeHeight // 如果是 Number 类型，返回原始高度
//   }

//   return nodeHeight - 80 // 默认情况下，返回减少后的高度
// }

export const dataToTreeData = ({
  data = [],
  nodeWidth = treeDataConfig.nodeWidth,
  nodeHeight = treeDataConfig.nodeHeight,
  customWidth = treeDataConfig.customWidth,
  customHeight = treeDataConfig.customHeight,
  smallCustomWidth = treeDataConfig.smallCustomWidth,
  smallCustomHeight = treeDataConfig.smallCustomHeight,
  numberWidth = treeDataConfig.numberWidth,
  numberHeight = treeDataConfig.numberHeight,
  layerGutter = treeDataConfig.layerGutter,
  nodeGutter = treeDataConfig.nodeGutter,
  lineCardWidth = treeDataConfig.lineCardWidth,
  lineCardHigth = treeDataConfig.lineCardHeight
}: TreeDataParams): TreeData => {
  const dataCopy = JSON.parse(JSON.stringify(data)) as NodeData[]; // 不影响旧数据，copy一份
  // 检查 dataCopy 的长度
  if (dataCopy.length === 0) {
    return false; // 如果没有数据，返回 false
  }

  const x6Nodes: X6Node[] = []; // 转换后的X6节点数组
  const x6Edges: X6Edge[] = []; // 转换后的x6边组合
  const idToX6Map: { [key: number]: X6Node } = {}; // id 对应对象map

  const calcNodes: CalcNode[] = []; // 用于计算节点下子树节点的宽高，x,y 数据
  const idToCalcNodesMap: { [key: number]: CalcNode } = {}; // 用于记录计算数据的 id 对应节点的map
  const collapsableNodes: { [key: number]: CollapsableNode } = {}; // 存在收缩展开子节点的功能， 用于记录收缩节点的数据
  const nodeHeightCopy = nodeHeight;
  const nodeWidthCopy = nodeWidth;
  const nodeTypeMap = {
    Custom: { shape: "treeNodeCustomCard", width: smallCustomWidth, height: customHeight },
    Number: { shape: "treeNodeNumberCard", width: numberWidth, height: numberHeight },
    smallCustom: { shape: "treeNodeSmallCustomCard", width: smallCustomWidth, height: smallCustomHeight },
    Line: { shape: "treeLineCard", width: lineCardWidth, height: lineCardHigth }
  };
  dataCopy.forEach(node => {
    // 获取节点的形状、宽度和高度
    const nodeConfig = nodeTypeMap[node.type] || { shape: "treeNodeCard", width: nodeWidthCopy, height: nodeHeightCopy };

    const nodeShape = nodeConfig.shape;
    const nodeWidth = nodeConfig.width;
    const nodeHeight = nodeConfig.height;

    const x6Node = {
      id: node.code, // 使用 code 作为 id
      shape: nodeShape,
      width: nodeWidth,
      height: calculateNodeHeight(node, nodeHeight),
      x: 0,
      y: 0,
      data: {
        ...node // 保留额外数据
      }
    };
    idToX6Map[node.code] = x6Node; // 使用 code 作为 key
    x6Nodes.push(x6Node);

    const calcNode = {
      ...node,
      width: nodeWidth,
      height: calculateNodeHeight(node, nodeHeight),
      subTreeWidth: 0,
      subTreeHeight: calculateNodeHeight(node, nodeHeight),
      usedWidth: 0 // 已经使用了的宽度
    };
    calcNodes.push(calcNode);
    idToCalcNodesMap[node.code] = calcNode; // 使用 code 作为 key
  });

  // 先排序，防止后端传回/生成的数据顺序有错
  dataCopy.sort((a, b) => {
    // 先按 layer 降序排序
    if (a.layer !== b.layer) {
      return b.layer - a.layer;
    }

    // 同一层内按 pCode 升序排序
    return a.pCode - b.pCode;
  });

  console.log("dataCopy", dataCopy);
  // 开始计算每个节点子树的宽度，由底向上更新
  dataCopy.forEach(node => {
    const pCode = node.pCode; // 获取父节点的Id
    const maxSubtreeWidth = Math.max(idToCalcNodesMap[node.code].subTreeWidth, idToCalcNodesMap[node.code].width);
    idToCalcNodesMap[node.code].subTreeWidth = maxSubtreeWidth;
    // 存在父节点更新父节点数据
    if (pCode) {
      const parentNode = idToCalcNodesMap[pCode];
      if (parentNode.subTreeWidth === 0) {
        parentNode.subTreeWidth += maxSubtreeWidth;
      } else {
        parentNode.subTreeWidth += maxSubtreeWidth + nodeGutter;
      }
    }
  });

  // 准备开始计算每个节点的x, y
  const fromRootToLeaf = JSON.parse(JSON.stringify(data));

  idToX6Map[-1].x = Math.round(idToCalcNodesMap[-1].subTreeWidth / 2) - nodeWidth / 2; // 根树的x结点
  idToX6Map[-1].y = 200;
  fromRootToLeaf.sort((a, b) => {
    if (a.layer !== b.layer) {
      return a.layer - b.layer;
    }
    return a.pCode - b.pCode;
  });

  fromRootToLeaf.forEach(node => {
    if (node.code === -1) {
      return;
    }
    const calcNode = idToCalcNodesMap[node.code];
    const x6Node = idToX6Map[node.code];
    const pCode = calcNode.pCode;
    const parentCalcNode = idToCalcNodesMap[pCode];
    const parentX6Node = idToX6Map[pCode];
    const subTreeStartX =
      parentX6Node.x + Math.round(calcNode.width / 2 - parentCalcNode.subTreeWidth / 2) + parentCalcNode.usedWidth;
    const subTreeStartY = parentX6Node.y + layerGutter + nodeHeight - 100;
    const nodeX = Math.round(subTreeStartX + calcNode.subTreeWidth / 2 - calcNode.width / 2);
    let changeNumber = 0;
    let ishas = false;
    const determineHierarchicalData = findLayerWithNumberType(dataCopy);
    determineHierarchicalData.forEach(item => {
      if (item.exists && item.layer === x6Node.data.layer) {
        changeNumber = x6Node.data.layer * 75;
        ishas = item.exists;
      }
    });
    // 类型为组数据是x轴往负方向移动
    const OFFSET_CUSTOM_CARD = -300;
    const OFFSET_NUMBER_CARD = changeNumber + 20;
    const OFFSET_SMALL_CUSTOM_CARD = -180;
    const OFFSET_HAS = 75;

    // 使用对象映射 shape 到偏移量
    const shapeOffsetMap = {
      treeNodeCustomCard: OFFSET_CUSTOM_CARD,
      treeNodeNumberCard: OFFSET_NUMBER_CARD,
      treeNodeSmallCustomCard: OFFSET_SMALL_CUSTOM_CARD
    };
    // 计算 x6Node.x
    const defaultOffset = ishas ? OFFSET_HAS : 0;

    // 这里我们将 treeNodeCustomCard 的逻辑与 treeNodeSmallCustomCard 逻辑合并
    if (x6Node.shape === "treeNodeCustomCard") {
      // 这里可以根据需要添加与 treeNodeSmallCustomCard 相同的逻辑
      x6Node.x = nodeX + (shapeOffsetMap.treeNodeSmallCustomCard || defaultOffset);
    } else {
      x6Node.x = nodeX + (shapeOffsetMap[x6Node.shape] || defaultOffset);
    }

    // 统一 y 轴的计算逻辑
    x6Node.y = subTreeStartY - 35;

    if (parentCalcNode.code !== -1) {
      x6Edges.push({
        source: parentX6Node.id,
        target: `expand-${parentX6Node.id}`,
        attrs: {
          line: {
            fill: "none",
            strokeLinejoin: "round",
            strokeWidth: 2,
            stroke: "#8f8f8f",
            sourceMarker: null,
            targetMarker: null
          }
        }
      });

      x6Edges.push({
        source: { cell: `expand-${parentX6Node.id}`, port: "bottom" },
        target: { cell: x6Node.id as string, port: "top" },
        attrs: {
          line: {
            fill: "none",
            strokeLinejoin: "round",
            strokeWidth: 2,
            stroke: "#8f8f8f",
            sourceMarker: null,
            targetMarker: null
          }
        },
        router: {
          name: "orth",
          args: {
            offset: "center",
            direction: "B"
          }
        }
      });
      if (parentCalcNode.type !== "Line") {
        if (!collapsableNodes[parentCalcNode.code]) {
          collapsableNodes[parentCalcNode.code] = {
            shape: "treeCollapsAbleNode",
            width: 40,
            height: 40,
            borderRadius: 50,
            x: parentX6Node.x + Math.round(parentCalcNode.width / 2) - 20,
            y: parentX6Node.y + parentCalcNode.height + layerGutter / 5 - 20,
            data: {
              expand: !calcNode.isShow,
              children: [calcNode.code],
              self: parentCalcNode.code,
              layer: parentCalcNode.layer
            },
            ports: {
              bottom: {
                position: "bottom",
                attrs: {
                  rect: {
                    magnet: true,
                    stroke: "#8f8f8f"
                  }
                }
              }
            }
          };
        } else {
          collapsableNodes[parentCalcNode.code]?.data?.children.push(calcNode.code);
        }
      } else {
        if (!collapsableNodes[parentCalcNode.code]) {
          collapsableNodes[parentCalcNode.code] = {
            shape: "connectEmptyBoxesCard",
            width: 40,
            height: 40,
            borderRadius: 50,
            x: parentX6Node.x + Math.round(parentCalcNode.width / 2) - 20,
            y: parentX6Node.y + parentCalcNode.height + layerGutter / 5 - 20,
            ports: {
              bottom: {
                position: "bottom",
                attrs: {
                  rect: {
                    magnet: true,
                    stroke: "#8f8f8f"
                  }
                }
              }
            }
          };
        }
      }
    }

    if (parentCalcNode.usedWidth === 0) {
      parentCalcNode.usedWidth += calcNode.subTreeWidth + nodeGutter;
    } else {
      parentCalcNode.usedWidth += calcNode.subTreeWidth + nodeGutter;
    }
  });

  return {
    nodes: [
      ...x6Nodes.filter(item => item.id !== -1),
      ...Object.keys(collapsableNodes).map(key => ({ ...collapsableNodes[key], id: `expand-${key}` }))
    ],
    edges: x6Edges,
    size: {
      width: idToCalcNodesMap[-1].subTreeWidth,
      height: Math.max(...calcNodes.map(item => item.layer)) * (nodeHeight + layerGutter) - layerGutter
    }
  };
};
export function removeItemByCode(array, code) {
  return array.reduce((acc, item) => {
    // 递归删除子项
    if (item.children) {
      item.children = removeItemByCode(item.children, code);
    }

    // 只保留 code 不等于 data.code 的项
    if (item.code !== code) {
      acc.push(item);
    }

    return acc;
  }, []);
}
// * 处理 Custom 类型的对象，添加顺序、children 总长度和同级别数量字段
export function processCustomItems(data) {
  const layerMap = new Map();

  // 首先构建一个层级映射，方便快速查找同级别的 Custom 对象
  data.forEach(item => {
    if (item.type === "Custom") {
      if (!layerMap.has(item.layer)) {
        layerMap.set(item.layer, []);
      }
      layerMap.get(item.layer).push(item);
    }
  });

  // 处理每个 Custom 对象
  data.forEach(item => {
    if (item.type === "Custom") {
      const sameLayerItems = layerMap.get(item.layer) || [];

      // 计算同级别下 children 数组的总长度
      const numberTotal = sameLayerItems.reduce((sum, currentItem) => {
        return sum + (currentItem.children ? currentItem.children.length : 0);
      }, 0);

      // 为当前对象添加顺序字段
      item.order = sameLayerItems.indexOf(item) + 1; // 添加表示顺序的字段，+1 使其从 1 开始

      // 添加同级别下 children 数组的总长度字段
      item.numberTotal = numberTotal;

      // 添加同级别 Custom 对象的数量字段
      item.numberOlder = sameLayerItems.length; // 同级别的 Custom 对象数量
    }
  });
}
